package db

import (
	"errors"
	"time"

	"os"

	"fmt"

	"github.com/astaxie/beego"
	mgo "gopkg.in/mgo.v2"
)

var Session *mgo.Session

func init() {
	session, err := Open()
	if err != nil || session == nil {
		beego.Error("mongodb init error!" + err.Error())
		os.Exit(1)
	}
	defer session.Close()
}
func Open() (*mgo.Session, error) {
	var mongoHost string
	if os.Getenv("MONGODB_HOST") != "" && os.Getenv("MONGODB_PORT") != "" {
		mongoHost = fmt.Sprintf("%s:%s", os.Getenv("MONGODB_HOST"), os.Getenv("MONGODB_PORT"))
	} else {
		mongoHost = beego.AppConfig.String("mongoURI")
	}
	beego.Info("mongoHost:", mongoHost)
	if Session == nil {
		login := &mgo.DialInfo{
			Addrs:    []string{mongoHost},
			Timeout:  60 * time.Second,
			Database: beego.AppConfig.String("mongoDB"),
			// Username: beego.AppConfig.String("mongoUser"),
			// Password: beego.AppConfig.String("mongoPass"),
		}
		//log.Debug("Connectting mongodb, host:", login.Addrs, "user:", login.Username, ", password:", login.Password, ", db:", login.Database)
		session, err := mgo.DialWithInfo(login)
		if err != nil {
			beego.Error(err)
			//log.Error(err.Error())
			return nil, err
		}
		Session = session
		return session.Clone(), err
	}
	return Session, nil
}

func GetSession() (*mgo.Session, error) {
	if Session == nil {
		return Open()
	}
	return Session.Clone(), nil
}

func CloseSession(session *mgo.Session) {
	if session != nil {
		session.Close()
	}
}

func GetDB(session *mgo.Session) (*mgo.Database, error) {
	if session == nil {
		var err error
		session, err = GetSession()
		if err != nil {
			return nil, err
		}
	}
	db := session.DB("")
	return db, nil
}

func GetCollection(collection string, db *mgo.Database) (*mgo.Collection, error) {
	if len(collection) == 0 {
		return nil, errors.New("Don't use empty collection name")
	}
	if db == nil {
		var err error
		db, err = GetDB(nil)

		if err != nil {
			return nil, err
		}
	}
	co := db.C(collection)
	return co, nil
}

type MongoSession struct {
	Session *mgo.Session
	DB      *mgo.Database
}

func GetMongoSession() *MongoSession {
	session, err := GetSession()
	if err != nil {
		return nil
	}
	db, err := GetDB(session)
	if err != nil {
		return nil
	}
	return &MongoSession{
		Session: session,
		DB:      db,
	}
}

func (e *MongoSession) Insert(collection string, data ...interface{}) bool {
	coll, err := GetCollection(collection, e.DB)
	if err != nil {
		return false
	}
	err = coll.Insert(data...)
	if err != nil {
		beego.Error("insert data in " + collection + " error," + err.Error())
		return false
	}
	return true
}

func (e *MongoSession) GetCollection(collection string) *mgo.Collection {
	coll, err := GetCollection(collection, e.DB)
	if err != nil {
		return nil
	}
	return coll
}
func (e *MongoSession) RemoveAll(collection string) bool {
	coll, err := GetCollection(collection, e.DB)
	if err != nil {
		return false
	}
	_, err = coll.RemoveAll(nil)
	if err == nil {
		return true
	}
	return false
}

func (e *MongoSession) Close() {
	if e.Session != nil {
		CloseSession(e.Session)
	}
}
